home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / os.c < prev    next >
C/C++ Source or Header  |  1996-05-26  |  14KB  |  675 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * OS specific functions
  5.   * 
  6.   * (c) 1995 Bernd Schmidt
  7.   * (c) 1996 Marcus Sundberg
  8.   */
  9.  
  10. #include "sysconfig.h"
  11. #include "sysdeps.h"
  12.  
  13. #include "config.h"
  14. #include "options.h"
  15. #include "memory.h"
  16. #include "custom.h"
  17. #include "os.h"
  18.  
  19. #ifdef HAVE_LINUX_JOYSTICK_H
  20.  
  21. static int js0;
  22. static int joystickpresent = 0;
  23.  
  24. struct JS_DATA_TYPE jscal;
  25.  
  26. void read_joystick(UWORD *dir, int *button)
  27. {
  28.     static int minx = MAXINT, maxx = MININT,
  29.                miny = MAXINT, maxy = MININT;
  30.     int left = 0, right = 0, top = 0, bot = 0;
  31.     struct JS_DATA_TYPE buffer;
  32.     int len;
  33.     
  34.     *dir = 0;
  35.     *button = 0;
  36.     if (!joystickpresent)
  37.         return;
  38.     
  39.     len = read(js0, &buffer, sizeof(buffer));
  40.     if (len != sizeof(buffer)) 
  41.         return;
  42.     
  43.     if (buffer.x < minx) minx = buffer.x;
  44.     if (buffer.y < miny) miny = buffer.y;
  45.     if (buffer.x > maxx) maxx = buffer.x;
  46.     if (buffer.y > maxy) maxy = buffer.y;
  47.     
  48.     if (buffer.x < (minx + (maxx-minx)/3))
  49.         left = 1;
  50.     else if (buffer.x > (minx + 2*(maxx-minx)/3))
  51.         right = 1;
  52.  
  53.     if (buffer.y < (miny + (maxy-miny)/3))
  54.         top = 1;
  55.     else if (buffer.y > (miny + 2*(maxy-miny)/3))
  56.         bot = 1;
  57.         
  58.     if (left) top = !top;
  59.     if (right) bot = !bot;
  60.     *dir = bot | (right << 1) | (top << 8) | (left << 9);
  61.     *button = (buffer.buttons & 3) != 0;
  62. }
  63.  
  64. void init_joystick(void)
  65. {
  66.     js0 = open("/dev/js0", O_RDONLY);
  67.     if (js0 < 0)
  68.         return;
  69.     joystickpresent = 1;
  70. }
  71.  
  72. void close_joystick(void)
  73. {
  74.     if (joystickpresent)
  75.     close(js0);
  76. }
  77.  
  78. #elif defined(__DOS__)
  79.  
  80. static int joystickpresent = 0;
  81.  
  82. void read_joystick(UWORD *dir, int *button)
  83. {
  84.     static int minx = MAXINT, maxx = MININT,
  85.            miny = MAXINT, maxy = MININT;
  86.     int left = 0, right = 0, top = 0, bot = 0;
  87.     char JoyPort;
  88.     int laps, JoyX, JoyY;
  89.  
  90.     *dir = 0;
  91.     *button = 0;
  92.     if (!joystickpresent)
  93.     return;
  94.  
  95.     JoyX = 0;
  96.     JoyY = 0;
  97.     laps = 0;
  98.     __asm__ __volatile__("cli");
  99.     outportb(0x201, 0xff);
  100.     do {
  101.     JoyPort = inportb(0x201);
  102.     JoyX = JoyX + (JoyPort & 1);
  103.     JoyY = JoyY + ((JoyPort & 2) >> 1);
  104.     laps++;
  105.     } while(((JoyPort & 3) != 0) && (laps != 65535));
  106.     __asm__ __volatile__("sti");
  107.  
  108.     if (JoyX < minx) minx = JoyX;
  109.     if (JoyY < miny) miny = JoyY;
  110.     if (JoyX > maxx) maxx = JoyX;
  111.     if (JoyY > maxy) maxy = JoyY;
  112.  
  113.     if (JoyX < (minx + (maxx-minx)/3))
  114.     left = 1;
  115.     else if (JoyX > (minx + 2*(maxx-minx)/3))
  116.     right = 1;
  117.  
  118.     if (JoyY < (miny + (maxy-miny)/3))
  119.     top = 1;
  120.     else if (JoyY > (miny + 2*(maxy-miny)/3))
  121.     bot = 1;
  122.  
  123.     if (left) top = !top;
  124.     if (right) bot = !bot;
  125.     *dir = bot | (right << 1) | (top << 8) | (left << 9);
  126.     *button = ((~JoyPort) & 48) != 0;
  127. }
  128.  
  129. void init_joystick(void)
  130. {
  131.     int laps = 0;
  132.     char JoyPort;
  133.     __asm__ __volatile__("cli");
  134.     outportb(0x201, 0xff);
  135.     do {
  136.     JoyPort = inportb(0x201);
  137.     laps++;
  138.     } while(((JoyPort & 3) != 0) && (laps != 65535));
  139.     __asm__ __volatile__("sti");
  140.     if (laps != 65535)
  141.     joystickpresent = 1;
  142. }
  143.  
  144. void close_joystick(void)
  145. {
  146. }
  147.  
  148. #else
  149. void read_joystick(UWORD *dir, int *button)
  150. {
  151.     *dir = 0;
  152.     *button = 0;
  153. }
  154.  
  155. void init_joystick(void)
  156. {
  157. }
  158.  
  159. void close_joystick(void)
  160. {
  161. }
  162.  
  163. #endif
  164.  
  165. CPTR audlc[4], audpt[4];
  166. UWORD audvol[4], audper[4], audlen[4], audwlen[4];
  167. int audwper[4];
  168. UWORD auddat[4];
  169. int audsnum[4];
  170.  
  171. /* Audio states. This is not an exact representation of the Audio State Machine
  172.  * (HRM p. 166), but a simplification. To be honest, I don't completely
  173.  * understand that picture yet.
  174.  */
  175. int audst[4];
  176.  
  177. int sound_table[256][64];
  178.  
  179. static void init_sound_table16(void)
  180. {
  181.     int i,j;
  182.     
  183.     for (i = 0; i < 256; i++)
  184.     for (j = 0; j < 64; j++)
  185.         sound_table[i][j] = j * (BYTE)i;
  186. }
  187.  
  188. static void init_sound_table8(void)
  189. {
  190.     int i,j;
  191.     
  192.     for (i = 0; i < 256; i++)
  193.     for (j = 0; j < 64; j++)
  194.         sound_table[i][j] = (j * (BYTE)i) / 256;
  195. }
  196.  
  197. #ifdef LINUX_SOUND
  198.  
  199. #include <sys/ioctl.h>
  200. #include <sys/soundcard.h>
  201.  
  202. static const int n_frames = 10;
  203.  
  204. /* The buffer is too large... */
  205. static UWORD buffer[44100], *bufpt;
  206. static UBYTE snddata[4];
  207.  
  208. static int frames = 0;
  209. static int smplcnt = 0;
  210. static int dsprate, dspbits, dspomit = 0;
  211. static int sndbufsize;
  212.  
  213. static int sfd;
  214. static int have_sound;
  215.  
  216. int init_sound (void)
  217. {
  218.     int tmp;
  219.     int rate;
  220.     
  221.     unsigned long formats;
  222.     
  223.     sfd = open ("/dev/dsp", O_WRONLY);
  224.     have_sound = !(sfd < 0);
  225.     if (!have_sound) {
  226.     return 0;
  227.     }
  228.     
  229.     ioctl (sfd, SNDCTL_DSP_GETFMTS, &formats);
  230.  
  231.     tmp = 0x0004000D;
  232.     ioctl (sfd, SNDCTL_DSP_SETFRAGMENT, &tmp);
  233.     ioctl (sfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
  234. #ifndef LINUX_SOUND_SLOW_MACHINE
  235.     dspbits = 16;
  236.     ioctl(sfd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
  237.     ioctl(sfd, SOUND_PCM_READ_BITS, &dspbits);
  238.     if (dspbits != 16)
  239. #endif
  240.     {
  241.     dspbits = 8;
  242.     ioctl(sfd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
  243.     ioctl(sfd, SOUND_PCM_READ_BITS, &dspbits);
  244.     if (dspbits != 8)
  245.         return 0;
  246.     }
  247.  
  248.     tmp = 0;
  249.     ioctl(sfd, SNDCTL_DSP_STEREO, &tmp);
  250.     
  251. #ifndef LINUX_SOUND_SLOW_MACHINE
  252.     dsprate = 0;
  253.     rate = 44100;
  254.     ioctl(sfd, SNDCTL_DSP_SPEED, &rate);
  255.     ioctl(sfd, SOUND_PCM_READ_RATE, &rate);
  256.     if (rate < 43000 || rate > 45000) 
  257. #endif
  258.     {
  259.     dsprate = 1;
  260.     rate = 22050;
  261.     ioctl(sfd, SNDCTL_DSP_SPEED, &rate);
  262.     ioctl(sfd, SOUND_PCM_READ_RATE, &rate);
  263.     /* Some soundcards return 22222 here. */
  264.     if (rate < 21000 || rate > 23000)
  265.         return 0;
  266.     }
  267.     if (dspbits == 16) {
  268.     /* Will this break horribly on Linux/Alpha? Possible... */
  269.     if (!(formats & AFMT_S16_LE))
  270.         return 0;
  271.     init_sound_table16 ();
  272.     } else {
  273.     if (!(formats & AFMT_U8))
  274.         return 0;
  275.     init_sound_table8 ();
  276.     }
  277.     printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
  278.         dspbits, rate, sndbufsize);
  279.     audst[0] = audst[1] = audst[2] = audst[3] = 0;
  280.     bufpt = buffer;
  281.     frames = n_frames;
  282.     smplcnt = 0;
  283.     return 1;
  284. }
  285.  
  286. static void channel_reload (int c)
  287. {
  288.     audst[c] = 1;
  289.     audpt[c] = audlc[c];
  290.     audwper[c] = 0;
  291.     audwlen[c] = audlen[c];
  292.     audsnum[c] = 1;    
  293. }
  294.  
  295. void do_sound (void)
  296. {
  297.     smplcnt -= 227;
  298.     while (smplcnt < 0) {
  299.     int i;
  300.     smplcnt += 80;
  301.     dspomit ^= dsprate;
  302.     
  303.     for(i = 0; i < 4; i++) {
  304.         if (dmaen (1<<i)) {
  305.         if (audst[i] == 0) {        
  306.             /* DMA was turned on for this channel */
  307.             channel_reload (i);
  308.             continue;
  309.         }
  310.         
  311.         if (audwper[i] <= 0) {
  312.             audwper[i] += audper[i];
  313.             if (audst[i] == 1) {
  314.             /*  Starting a sample, cause interrupt */
  315.             put_word (0xDFF09C, 0x8000 | (0x80 << i));
  316.             audst[i] = 2;
  317.             }
  318.             audsnum[i] ^= 1;
  319.             if (audsnum[i] == 0) {
  320.             auddat[i] = get_word (audpt[i]);
  321.             audpt[i] += 2;
  322.             audwlen[i]--;
  323.             if (audwlen[i] == 0) {
  324.                 channel_reload (i);
  325.             }
  326.             }
  327.         }
  328.         if (adkcon & (0x11 << i)) {
  329.             snddata[i] = 0;
  330.             audsnum[i] ^= 2;
  331.             audsnum[i] |= 1;
  332.             if (i < 3) {
  333.             if (adkcon & (0x11 << i)) {
  334.                 if (audsnum[i] & 2)
  335.                 audvol[i+1] = auddat[i];
  336.                 else
  337.                 audper[i+1] = auddat[i];
  338.             } else if (adkcon & (1 << i)) {
  339.                 audvol[i+1] = auddat[i];
  340.             } else {
  341.                 audper[i+1] = auddat[i];
  342.             }
  343.             }
  344.         } else {
  345.             snddata[i] = audsnum[i] & 1 ? auddat[i] : auddat[i] >> 8;
  346.         }
  347.         audwper[i] -= 80;        
  348.         } else 
  349.             audst[i] = snddata[i] = 0;
  350.     }
  351.     if (dspbits == 16) {
  352.         if (dspomit == 0)
  353.         *bufpt++ = (sound_table[snddata[0]][audvol[0]] 
  354.                 + sound_table[snddata[1]][audvol[1]]
  355.                 + sound_table[snddata[2]][audvol[2]] 
  356.                 + sound_table[snddata[3]][audvol[3]]);
  357.     } else {
  358.         unsigned char *bp = (unsigned char *)bufpt;
  359.         if (dspomit == 0)
  360.         *bp++ = (sound_table[snddata[0]][audvol[0]] 
  361.              + sound_table[snddata[1]][audvol[1]]
  362.              + sound_table[snddata[2]][audvol[2]] 
  363.              + sound_table[snddata[3]][audvol[3]] + 128);
  364.         bufpt = (UWORD *)bp;
  365.     }
  366.     if ((char *)bufpt - (char *)buffer >= sndbufsize) {
  367.         write(sfd, buffer, sndbufsize);
  368.         bufpt = buffer;
  369.     }
  370.     }
  371. }
  372.  
  373. #elif defined(AF_SOUND)
  374.  
  375. #include <AF/AFlib.h>
  376.  
  377. /* The buffer is too large... */
  378. static UWORD buffer[44100], *bufpt;
  379. static UBYTE snddata[4];
  380.  
  381. static int smplcnt = 0;
  382. static int dspbits = 0;
  383. static int sndbufsize;
  384.  
  385. static AFAudioConn  *aud;
  386. static AC            ac;
  387. static long          count = 0;
  388. static long          aftime;
  389. static int           rate;
  390. static int           freq_divisor;    
  391.  
  392.  
  393. static int have_sound;
  394.  
  395. int init_sound (void)
  396. {
  397.     AFSetACAttributes   attributes;
  398.     AFDeviceDescriptor *aDev;
  399.     int                 device;
  400.     
  401.     aud = AFOpenAudioConn(NULL);
  402.     have_sound = !(aud == NULL);
  403.     if (!have_sound) {
  404.     return 0;
  405.     }
  406.     
  407.     for(device = 0; device < ANumberOfAudioDevices(aud); device++) {
  408.     aDev = AAudioDeviceDescriptor(aud, device);
  409.     rate = aDev->playSampleFreq;
  410.     sndbufsize = (rate / 8) * 4;
  411.     if(aDev->inputsFromPhone == 0
  412.        && aDev->outputsToPhone == 0
  413.        && aDev->playNchannels == 1)
  414.         break;
  415.     }
  416.     if (device == ANumberOfAudioDevices(aud)) {
  417.     return 0;
  418.     }
  419.     
  420.     dspbits = 16;
  421.     attributes.type = LIN16;
  422.     ac = AFCreateAC(aud, device, ACEncodingType, &attributes);
  423.     aftime = AFGetTime(ac);
  424.  
  425.     if (dspbits == 16) {
  426.     init_sound_table16 ();
  427.     } else {
  428.     init_sound_table8 ();
  429.     }
  430.  
  431.     freq_divisor = 44100 / rate;
  432.     
  433.     audst[0] = audst[1] = audst[2] = audst[3] = 0;
  434.     bufpt = buffer;
  435.     smplcnt = 0;
  436.     printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n", dspbits, rate, sndbufsize);
  437.     return 1;
  438. }
  439.  
  440. static void channel_reload (int c)
  441. {
  442.     audst[c] = 1;
  443.     audpt[c] = audlc[c];
  444.     audwper[c] = 0;
  445.     audwlen[c] = audlen[c];
  446.     audsnum[c] = 1;    
  447. }
  448.  
  449. void do_sound (void)
  450. {
  451.     smplcnt -= 227;
  452.     while (smplcnt < 0) {
  453.     int i;
  454.     smplcnt += 80;
  455.     
  456.     for(i = 0; i < 4; i++) {
  457.         if (dmaen (1<<i)) {
  458.         if (audst[i] == 0) {        
  459.             /* DMA was turned on for this channel */
  460.             channel_reload (i);
  461.             continue;
  462.         }
  463.         
  464.         if (audwper[i] <= 0) {
  465.             audwper[i] += audper[i];
  466.             if (audst[i] == 1) {
  467.             /*  Starting a sample, cause interrupt */
  468.             put_word (0xDFF09C, 0x8000 | (0x80 << i));
  469.             audst[i] = 2;
  470.             }
  471.             audsnum[i] ^= 1;
  472.             if (audsnum[i] == 0) {
  473.             auddat[i] = get_word (audpt[i]);
  474.             audpt[i] += 2;
  475.             audwlen[i]--;
  476.             if (audwlen[i] == 0) {
  477.                 channel_reload (i);
  478.             }
  479.             }
  480.         }
  481.         if (adkcon & (0x11 << i)) {
  482.             snddata[i] = 0;
  483.             audsnum[i] ^= 2;
  484.             audsnum[i] |= 1;
  485.             if (i < 3) {
  486.             if (adkcon & (0x11 << i)) {
  487.                 if (audsnum[i] & 2)
  488.                 audvol[i+1] = auddat[i];
  489.                 else
  490.                 audper[i+1] = auddat[i];
  491.             } else if (adkcon & (1 << i)) {
  492.                 audvol[i+1] = auddat[i];
  493.             } else {
  494.                 audper[i+1] = auddat[i];
  495.             }
  496.             }
  497.         } else {
  498.             snddata[i] = audsnum[i] & 1 ? auddat[i] : auddat[i] >> 8;
  499.         }
  500.         audwper[i] -= 80;        
  501.         } else 
  502.             audst[i] = snddata[i] = 0;
  503.     }
  504.     if ((count++ % frq_divisor) == 0) {
  505.         long size;
  506.         *bufpt++ = (sound_table[snddata[0]][audvol[0]] 
  507.             + sound_table[snddata[1]][audvol[1]]
  508.             + sound_table[snddata[2]][audvol[2]] 
  509.             + sound_table[snddata[3]][audvol[3]];
  510.         size = (char *)bufpt - (char *)buffer;
  511.         if (size >= sndbufsize) {
  512.         if (AFGetTime(ac) > aftime)
  513.             aftime = AFGetTime(ac);
  514.         AFPlaySamples(ac, aftime, size, (unsigned char*) buffer);
  515.         aftime += size / 2;
  516.         bufpt = buffer;
  517.         }
  518.     }
  519.     }
  520. }
  521.  
  522. #elif defined(__mac__)
  523.  
  524. #include <Sound.h>
  525.  
  526. static SndChannelPtr newChannel;
  527. static ExtSoundHeader theSndBuffer;
  528. static SndCommand theCmd;
  529. static const int n_frames = 10;
  530.  
  531. /* The buffer is too large... */
  532. static UWORD buffer0[44100], buffer1[44100], *bufpt;
  533. static UBYTE snddata[4];
  534.  
  535. static int frames = 0;
  536. static int smplcnt = 0;
  537. static long count = 0;
  538. static int have_sound;
  539. static int sndbufsize=44100;
  540. static int nextbuf=0;
  541. static Boolean sFlag=true;
  542.  
  543. int init_sound (void)
  544. {    
  545.     if (SndNewChannel(&newChannel, sampledSynth, initMono, NULL)) 
  546.     return 0;
  547.     init_sound_table8 ();
  548.     smplcnt = 0;
  549.     bufpt = buffer0;
  550.     return 1;
  551. }
  552.  
  553. static void channel_reload (int c)
  554. {
  555.     audst[c] = 1;
  556.     audpt[c] = audlc[c];
  557.     audwper[c] = 0;
  558.     audwlen[c] = audlen[c];
  559.     audsnum[c] = 1;    
  560. }
  561.  
  562. void do_sound (void)
  563. {
  564.     unsigned char *bp;
  565.     
  566.     smplcnt -= 227;
  567.     while (smplcnt < 0) {
  568.     int i;
  569.     smplcnt += 80;
  570.     
  571.     for(i = 0; i < 4; i++) {
  572.         if (dmaen (1<<i)) {
  573.         if (audst[i] == 0) {        
  574.             /* DMA was turned on for this channel */
  575.             channel_reload (i);
  576.             continue;
  577.         }
  578.         
  579.         if (audwper[i] <= 0) {
  580.             audwper[i] += audper[i];
  581.             if (audst[i] == 1) {
  582.             /*  Starting a sample, cause interrupt */
  583.             put_word (0xDFF09C, 0x8000 | (0x80 << i));
  584.             audst[i] = 2;
  585.             }
  586.             audsnum[i] ^= 1;
  587.             if (audsnum[i] == 0) {
  588.             auddat[i] = get_word (audpt[i]);
  589.             audpt[i] += 2;
  590.             audwlen[i]--;
  591.             if (audwlen[i] == 0) {
  592.                 channel_reload (i);
  593.             }
  594.             }
  595.         }
  596.         if (adkcon & (0x11 << i)) {
  597.             snddata[i] = 0;
  598.             audsnum[i] ^= 2;
  599.             audsnum[i] |= 1;
  600.             if (i < 3) {
  601.             if (adkcon & (0x11 << i)) {
  602.                 if (audsnum[i] & 2)
  603.                 audvol[i+1] = auddat[i];
  604.                 else
  605.                 audper[i+1] = auddat[i];
  606.             } else if (adkcon & (1 << i)) {
  607.                 audvol[i+1] = auddat[i];
  608.             } else {
  609.                 audper[i+1] = auddat[i];
  610.             }
  611.             }
  612.         } else {
  613.             snddata[i] = audsnum[i] & 1 ? auddat[i] : auddat[i] >> 8;
  614.         }
  615.         audwper[i] -= 80;        
  616.         } else 
  617.             audst[i] = snddata[i] = 0;
  618.     }
  619.     
  620.     bp = (unsigned char *)bufpt;
  621.     *bp++ = (sound_table[snddata[0]][audvol[0]] 
  622.          + sound_table[snddata[1]][audvol[1]]
  623.          + sound_table[snddata[2]][audvol[2]] 
  624.          + sound_table[snddata[3]][audvol[3]] + 128);
  625.     bufpt = (UWORD *)bp;
  626.     
  627.     if (nextbuf == 0) {
  628.         if ((char *)bufpt - (char *)buffer0 >= sndbufsize) {
  629.         nextbuf++;
  630.         bufpt = buffer1;
  631.             
  632.         theSndBuffer.samplePtr = (Ptr)buffer0;
  633.         theSndBuffer.numChannels = 1;
  634.         theSndBuffer.sampleRate = 0xac440000;
  635.         theSndBuffer.encode = extSH;
  636.         theSndBuffer.numFrames = sndbufsize;
  637.         theSndBuffer.sampleSize = 8;
  638.         theCmd.param1 = 0;
  639.         theCmd.param2 = (long)&theSndBuffer;
  640.         theCmd.cmd = bufferCmd;
  641.         SndDoCommand(newChannel, &theCmd, false);    
  642.         }
  643.     } else {
  644.         if ((char *)bufpt - (char *)buffer1 >= sndbufsize) {    
  645.         nextbuf=0;
  646.             bufpt = buffer0;
  647.             
  648.             theSndBuffer.samplePtr = (Ptr)buffer1;
  649.             theSndBuffer.numChannels = 1;
  650.         theSndBuffer.sampleRate = 0xac440000;
  651.         theSndBuffer.encode = extSH;
  652.         theSndBuffer.numFrames = sndbufsize;
  653.         theSndBuffer.sampleSize = 8;
  654.         theCmd.param1 = 0;
  655.         theCmd.param2 = (long)&theSndBuffer;
  656.         theCmd.cmd = bufferCmd;
  657.         SndDoCommand(newChannel, &theCmd, false);    
  658.         }
  659.     }
  660.     }
  661. }
  662.  
  663. #else
  664.  
  665. int init_sound (void)
  666. {
  667.     return 1;
  668. }
  669.  
  670. void do_sound (void)
  671. {
  672. }
  673.  
  674. #endif
  675.